// 问题：ABC427D - 游戏 动态规划 也非常好理解 。 有一组数据超时，不管了
#include <bits/stdc++.h>
using namespace std;

/**
 * solve 函数：解决单个测试用例的问题
 * 该函数读取输入数据，构建图结构，然后通过动态规划方法计算 Alice 是否能获胜
 */
void solve() {

  int n, m, k; // 输入变量：n为节点数，m为边数，k为步数限制

  string s; // s为每个节点的类型，'A'或其他
  cin >> n >> m >> k >> s;
  // 构建图的邻接表表示
  vector<int> to[200005];
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v;
    // 转换为0-based索引
    --u;
    --v;
    to[u].push_back(v); // 添加有向边u->v
    // to[v].push_back(u); // 添加有向边v->u（无向图）
  }

  // dp[i][v] 表示在第i步开始时，处于节点v的 当前玩家是否能获胜
  // 步数编号：1到2*k+1（总共2*k+1步）
  // 第1步：Alice执棋（游戏开始）
  // 第2步：Bob执棋
  // ...
  // 第2*k步：Bob执棋（最后一步移动）
  // 第2*k+1步：游戏结束，根据最终位置决定胜负
  vector<vector<int>> dp(k * 2 + 2, vector<int>(n)); // 大小改为2*k+2

  // 初始化最后一步（第2*k+1步）的状态
  // 游戏结束时，胜负只取决于最终位置的字符
  for (int v = 0; v < n; ++v) {
    // 如果最终位置字符是'A'，Alice获胜；否则Bob获胜
    // 只是在最后一步（第2*k步）时，这个"当前玩家"的概念需要特殊理解，因为这一步没有实际的移动操作。
    dp[k * 2 + 1][v] = (s[v] == 'A');
  }

  // 从后向前进行动态规划（从第2*k步到第1步）
  for (int i = k * 2; i >= 1; --i) {
    for (int v = 0; v < n; ++v) {
      // 默认当前玩家会输
      dp[i][v] = 0;

      // 遍历当前顶点的所有出边（后继顶点）
      for (int son : to[v]) {
        // 关键逻辑：如果存在一个后继顶点，使得下一个玩家会输
        // 那么当前玩家可以选择这个后继顶点来获胜
        if (!dp[i + 1][son]) {
          dp[i][v] = 1; // 当前玩家可以获胜
          break;        // 找到一个获胜策略即可
        }
      }
    }
  }

  // 输出结果：从第1步、顶点0（即题目中的顶点1）开始
  // dp[1][0]表示Alice在游戏开始时是否能获胜
  if (dp[1][0]) {
    puts("Alice");
  } else {
    puts("Bob");
  }
}

int main() {
  ios::sync_with_stdio(true);
  cin.tie(0);
  cout.tie(0);

  int t;
  cin >> t;

  while (t--) {
    solve();
  }

  return 0;
}